{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "采用PCA KPCA LDA不采用归一化 做数据降维以美国油田为例.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "toc_visible": true,
      "authorship_tag": "ABX9TyPjos6qD9VaewRp/vav/WtV",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/sunyingjian/-Logging-related-network/blob/master/%E9%87%87%E7%94%A8PCA_KPCA_LDA%E4%B8%8D%E9%87%87%E7%94%A8%E5%BD%92%E4%B8%80%E5%8C%96_%E5%81%9A%E6%95%B0%E6%8D%AE%E9%99%8D%E7%BB%B4%E4%BB%A5%E7%BE%8E%E5%9B%BD%E6%B2%B9%E7%94%B0%E4%B8%BA%E4%BE%8B.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Cqy3vXXOMI06",
        "colab_type": "text"
      },
      "source": [
        "### <font size=5px color=\"red\">✦ *Google Colab 突破90分钟自动断开:</font>\n",
        "<p><font size=3px > 每60分钟自动运行代码以刷新90分钟断开限制. 打开 developer-settings (在你的浏览器) 快速健 Ctrl+Shift+I 然后按console 输入以下代码 Enter. ( mac 按 Option+Command+I)</p><b>复制以下隐藏代码粉贴在浏览器console！！不要关闭浏览器以免失效</b>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3Z8cK8h2Avbv",
        "colab_type": "text"
      },
      "source": [
        "<code>function ClickConnect(){\n",
        "console.log(\"Working\"); \n",
        "document.querySelector(\"colab-connect-button\").click() \n",
        "}setInterval(ClickConnect,6000)</code>"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jtClEMAMLVHw",
        "colab_type": "code",
        "cellView": "both",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 35
        },
        "outputId": "c67dbc5f-984d-425d-8edf-13876027afa1"
      },
      "source": [
        "#@markdown <h3>← 输入了代码后运行以防止断开</h>\n",
        "\n",
        "\n",
        "import IPython\n",
        "from google.colab import output\n",
        "\n",
        "display(IPython.display.Javascript('''\n",
        " function ClickConnect(){\n",
        "   btn = document.querySelector(\"colab-connect-button\")\n",
        "   if (btn != null){\n",
        "     console.log(\"Click colab-connect-button\"); \n",
        "     btn.click() \n",
        "     }\n",
        "   \n",
        "   btn = document.getElementById('ok')\n",
        "   if (btn != null){\n",
        "     console.log(\"Click reconnect\"); \n",
        "     btn.click() \n",
        "     }\n",
        "  }\n",
        "  \n",
        "setInterval(ClickConnect,60000)\n",
        "'''))\n",
        "\n",
        "print(\"Done.\")"
      ],
      "execution_count": 1,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "application/javascript": [
              "\n",
              " function ClickConnect(){\n",
              "   btn = document.querySelector(\"colab-connect-button\")\n",
              "   if (btn != null){\n",
              "     console.log(\"Click colab-connect-button\"); \n",
              "     btn.click() \n",
              "     }\n",
              "   \n",
              "   btn = document.getElementById('ok')\n",
              "   if (btn != null){\n",
              "     console.log(\"Click reconnect\"); \n",
              "     btn.click() \n",
              "     }\n",
              "  }\n",
              "  \n",
              "setInterval(ClickConnect,60000)\n"
            ],
            "text/plain": [
              "<IPython.core.display.Javascript object>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "Done.\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2Kt3s4toryUA",
        "colab_type": "text"
      },
      "source": [
        "#准备数据"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9X6siHUprwnl",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 207
        },
        "outputId": "982f2dd0-ec91-4cf0-fb21-0a0923a44c6d"
      },
      "source": [
        "! git clone https://github.com/sunyingjian/numpy-.git\n",
        "! git clone https://github.com/seg/tutorials-2016.git"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Cloning into 'numpy-'...\n",
            "remote: Enumerating objects: 69, done.\u001b[K\n",
            "remote: Counting objects: 100% (69/69), done.\u001b[K\n",
            "remote: Compressing objects: 100% (69/69), done.\u001b[K\n",
            "remote: Total 69 (delta 23), reused 0 (delta 0), pack-reused 0\u001b[K\n",
            "Unpacking objects: 100% (69/69), done.\n",
            "Cloning into 'tutorials-2016'...\n",
            "remote: Enumerating objects: 161, done.\u001b[K\n",
            "remote: Total 161 (delta 0), reused 0 (delta 0), pack-reused 161\u001b[K\n",
            "Receiving objects: 100% (161/161), 16.86 MiB | 13.50 MiB/s, done.\n",
            "Resolving deltas: 100% (64/64), done.\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "rw0aebL3r2lS",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 124
        },
        "outputId": "05027778-ecc5-43fa-df50-167b022a53a9"
      },
      "source": [
        "import os\n",
        "from google.colab import drive\n",
        "drive.mount('/content/drive')"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Go to this URL in a browser: https://accounts.google.com/o/oauth2/auth?client_id=947318989803-6bn6qk8qdgf4n4g3pfee6491hc0brc4i.apps.googleusercontent.com&redirect_uri=urn%3aietf%3awg%3aoauth%3a2.0%3aoob&response_type=code&scope=email%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdocs.test%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdrive%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdrive.photos.readonly%20https%3a%2f%2fwww.googleapis.com%2fauth%2fpeopleapi.readonly\n",
            "\n",
            "Enter your authorization code:\n",
            "··········\n",
            "Mounted at /content/drive\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "K7PBrA4Yr8h_",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 407
        },
        "outputId": "add309cc-4a38-4d6a-c63e-84e8bf7f2860"
      },
      "source": [
        "%matplotlib inline\n",
        "#%matplotlib inline 可以在Ipython编译器里直接使用，功能是可以内嵌绘图，并且可以省略掉plt.show()这一步。\n",
        "import pandas as pd\n",
        "import numpy as np\n",
        "import matplotlib as mpl\n",
        "import matplotlib.pyplot as plt\n",
        "import matplotlib.colors as colors\n",
        "from mpl_toolkits.axes_grid1 import make_axes_locatable\n",
        "from pandas import set_option\n",
        "set_option(\"display.max_rows\", 10)#设置要显示的默认行数，显示的最大行数是10\n",
        "pd.options.mode.chained_assignment = None #为了在增加列表行数的时候防止出现setting with copy warning\n",
        "filename = 'facies_vectors.csv'\n",
        "training_data = pd.read_csv('/content/tutorials-2016/1610_Facies_classification/training_data.csv')\n",
        "training_data"
      ],
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>Facies</th>\n",
              "      <th>Formation</th>\n",
              "      <th>Well Name</th>\n",
              "      <th>Depth</th>\n",
              "      <th>GR</th>\n",
              "      <th>ILD_log10</th>\n",
              "      <th>DeltaPHI</th>\n",
              "      <th>PHIND</th>\n",
              "      <th>PE</th>\n",
              "      <th>NM_M</th>\n",
              "      <th>RELPOS</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>3</td>\n",
              "      <td>A1 SH</td>\n",
              "      <td>SHRIMPLIN</td>\n",
              "      <td>2793.0</td>\n",
              "      <td>77.450</td>\n",
              "      <td>0.664</td>\n",
              "      <td>9.900</td>\n",
              "      <td>11.915</td>\n",
              "      <td>4.600</td>\n",
              "      <td>1</td>\n",
              "      <td>1.000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>3</td>\n",
              "      <td>A1 SH</td>\n",
              "      <td>SHRIMPLIN</td>\n",
              "      <td>2793.5</td>\n",
              "      <td>78.260</td>\n",
              "      <td>0.661</td>\n",
              "      <td>14.200</td>\n",
              "      <td>12.565</td>\n",
              "      <td>4.100</td>\n",
              "      <td>1</td>\n",
              "      <td>0.979</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>3</td>\n",
              "      <td>A1 SH</td>\n",
              "      <td>SHRIMPLIN</td>\n",
              "      <td>2794.0</td>\n",
              "      <td>79.050</td>\n",
              "      <td>0.658</td>\n",
              "      <td>14.800</td>\n",
              "      <td>13.050</td>\n",
              "      <td>3.600</td>\n",
              "      <td>1</td>\n",
              "      <td>0.957</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>3</td>\n",
              "      <td>A1 SH</td>\n",
              "      <td>SHRIMPLIN</td>\n",
              "      <td>2794.5</td>\n",
              "      <td>86.100</td>\n",
              "      <td>0.655</td>\n",
              "      <td>13.900</td>\n",
              "      <td>13.115</td>\n",
              "      <td>3.500</td>\n",
              "      <td>1</td>\n",
              "      <td>0.936</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>3</td>\n",
              "      <td>A1 SH</td>\n",
              "      <td>SHRIMPLIN</td>\n",
              "      <td>2795.0</td>\n",
              "      <td>74.580</td>\n",
              "      <td>0.647</td>\n",
              "      <td>13.500</td>\n",
              "      <td>13.300</td>\n",
              "      <td>3.400</td>\n",
              "      <td>1</td>\n",
              "      <td>0.915</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>...</th>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3227</th>\n",
              "      <td>5</td>\n",
              "      <td>C LM</td>\n",
              "      <td>CHURCHMAN BIBLE</td>\n",
              "      <td>3120.5</td>\n",
              "      <td>46.719</td>\n",
              "      <td>0.947</td>\n",
              "      <td>1.828</td>\n",
              "      <td>7.254</td>\n",
              "      <td>3.617</td>\n",
              "      <td>2</td>\n",
              "      <td>0.685</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3228</th>\n",
              "      <td>5</td>\n",
              "      <td>C LM</td>\n",
              "      <td>CHURCHMAN BIBLE</td>\n",
              "      <td>3121.0</td>\n",
              "      <td>44.563</td>\n",
              "      <td>0.953</td>\n",
              "      <td>2.241</td>\n",
              "      <td>8.013</td>\n",
              "      <td>3.344</td>\n",
              "      <td>2</td>\n",
              "      <td>0.677</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3229</th>\n",
              "      <td>5</td>\n",
              "      <td>C LM</td>\n",
              "      <td>CHURCHMAN BIBLE</td>\n",
              "      <td>3121.5</td>\n",
              "      <td>49.719</td>\n",
              "      <td>0.964</td>\n",
              "      <td>2.925</td>\n",
              "      <td>8.013</td>\n",
              "      <td>3.190</td>\n",
              "      <td>2</td>\n",
              "      <td>0.669</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3230</th>\n",
              "      <td>5</td>\n",
              "      <td>C LM</td>\n",
              "      <td>CHURCHMAN BIBLE</td>\n",
              "      <td>3122.0</td>\n",
              "      <td>51.469</td>\n",
              "      <td>0.965</td>\n",
              "      <td>3.083</td>\n",
              "      <td>7.708</td>\n",
              "      <td>3.152</td>\n",
              "      <td>2</td>\n",
              "      <td>0.661</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3231</th>\n",
              "      <td>5</td>\n",
              "      <td>C LM</td>\n",
              "      <td>CHURCHMAN BIBLE</td>\n",
              "      <td>3122.5</td>\n",
              "      <td>50.031</td>\n",
              "      <td>0.970</td>\n",
              "      <td>2.609</td>\n",
              "      <td>6.668</td>\n",
              "      <td>3.295</td>\n",
              "      <td>2</td>\n",
              "      <td>0.653</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "<p>3232 rows × 11 columns</p>\n",
              "</div>"
            ],
            "text/plain": [
              "      Facies Formation        Well Name   Depth  ...   PHIND     PE  NM_M  RELPOS\n",
              "0          3     A1 SH        SHRIMPLIN  2793.0  ...  11.915  4.600     1   1.000\n",
              "1          3     A1 SH        SHRIMPLIN  2793.5  ...  12.565  4.100     1   0.979\n",
              "2          3     A1 SH        SHRIMPLIN  2794.0  ...  13.050  3.600     1   0.957\n",
              "3          3     A1 SH        SHRIMPLIN  2794.5  ...  13.115  3.500     1   0.936\n",
              "4          3     A1 SH        SHRIMPLIN  2795.0  ...  13.300  3.400     1   0.915\n",
              "...      ...       ...              ...     ...  ...     ...    ...   ...     ...\n",
              "3227       5      C LM  CHURCHMAN BIBLE  3120.5  ...   7.254  3.617     2   0.685\n",
              "3228       5      C LM  CHURCHMAN BIBLE  3121.0  ...   8.013  3.344     2   0.677\n",
              "3229       5      C LM  CHURCHMAN BIBLE  3121.5  ...   8.013  3.190     2   0.669\n",
              "3230       5      C LM  CHURCHMAN BIBLE  3122.0  ...   7.708  3.152     2   0.661\n",
              "3231       5      C LM  CHURCHMAN BIBLE  3122.5  ...   6.668  3.295     2   0.653\n",
              "\n",
              "[3232 rows x 11 columns]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 4
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "OXLr943cr_Zz",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 69
        },
        "outputId": "1440de05-d626-4385-f629-337270ad37b0"
      },
      "source": [
        "training_data['Well Name'] = training_data['Well Name'].astype('category')\n",
        "training_data['Formation'] = training_data['Formation'].astype('category')\n",
        "training_data['Well Name'].unique()"
      ],
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[SHRIMPLIN, SHANKLE, LUKE G U, CROSS H CATTLE, NOLAN, Recruit F9, NEWBY, CHURCHMAN BIBLE]\n",
              "Categories (8, object): [SHRIMPLIN, SHANKLE, LUKE G U, CROSS H CATTLE, NOLAN, Recruit F9, NEWBY,\n",
              "                         CHURCHMAN BIBLE]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 5
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "XgXfk6c-sD-f",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 288
        },
        "outputId": "2ef10d90-935d-4212-ae29-90f7972a5e72"
      },
      "source": [
        "# 1=sandstone  2=c_siltstone   3=f_siltstone \n",
        "# 4=marine_silt_shale 5=mudstone 6=wackestone 7=dolomite\n",
        "# 8=packstone 9=bafflestone\n",
        "facies_colors = ['#F4D03F', '#F5B041','#DC7633','#6E2C00',\n",
        "       '#1B4F72','#2E86C1', '#AED6F1', '#A569BD', '#196F3D']\n",
        "\n",
        "facies_labels = ['SS', 'CSiS', 'FSiS', 'SiSh', 'MS',\n",
        "                 'WS', 'D','PS', 'BS']\n",
        "#facies_color_map is a dictionary that maps facies labels\n",
        "#to their respective colors\n",
        "facies_color_map = {}\n",
        "for ind, label in enumerate(facies_labels):\n",
        "    facies_color_map[label] = facies_colors[ind]\n",
        "\n",
        "def label_facies(row, labels):\n",
        "    return labels[ row['Facies'] -1]\n",
        "    \n",
        "training_data.loc[:,'FaciesLabels'] = training_data.apply(lambda row: label_facies(row, facies_labels), axis=1) #建立标签\n",
        "training_data.describe()"
      ],
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>Facies</th>\n",
              "      <th>Depth</th>\n",
              "      <th>GR</th>\n",
              "      <th>ILD_log10</th>\n",
              "      <th>DeltaPHI</th>\n",
              "      <th>PHIND</th>\n",
              "      <th>PE</th>\n",
              "      <th>NM_M</th>\n",
              "      <th>RELPOS</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>count</th>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>mean</th>\n",
              "      <td>4.422030</td>\n",
              "      <td>2875.824567</td>\n",
              "      <td>66.135769</td>\n",
              "      <td>0.642719</td>\n",
              "      <td>3.559642</td>\n",
              "      <td>13.483213</td>\n",
              "      <td>3.725014</td>\n",
              "      <td>1.498453</td>\n",
              "      <td>0.520287</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>std</th>\n",
              "      <td>2.504243</td>\n",
              "      <td>131.006274</td>\n",
              "      <td>30.854826</td>\n",
              "      <td>0.241845</td>\n",
              "      <td>5.228948</td>\n",
              "      <td>7.698980</td>\n",
              "      <td>0.896152</td>\n",
              "      <td>0.500075</td>\n",
              "      <td>0.286792</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>min</th>\n",
              "      <td>1.000000</td>\n",
              "      <td>2573.500000</td>\n",
              "      <td>13.250000</td>\n",
              "      <td>-0.025949</td>\n",
              "      <td>-21.832000</td>\n",
              "      <td>0.550000</td>\n",
              "      <td>0.200000</td>\n",
              "      <td>1.000000</td>\n",
              "      <td>0.010000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>25%</th>\n",
              "      <td>2.000000</td>\n",
              "      <td>2791.000000</td>\n",
              "      <td>46.918750</td>\n",
              "      <td>0.492750</td>\n",
              "      <td>1.163750</td>\n",
              "      <td>8.346750</td>\n",
              "      <td>3.100000</td>\n",
              "      <td>1.000000</td>\n",
              "      <td>0.273000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>50%</th>\n",
              "      <td>4.000000</td>\n",
              "      <td>2893.500000</td>\n",
              "      <td>65.721500</td>\n",
              "      <td>0.624437</td>\n",
              "      <td>3.500000</td>\n",
              "      <td>12.150000</td>\n",
              "      <td>3.551500</td>\n",
              "      <td>1.000000</td>\n",
              "      <td>0.526000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>75%</th>\n",
              "      <td>6.000000</td>\n",
              "      <td>2980.000000</td>\n",
              "      <td>79.626250</td>\n",
              "      <td>0.812735</td>\n",
              "      <td>6.432500</td>\n",
              "      <td>16.453750</td>\n",
              "      <td>4.300000</td>\n",
              "      <td>2.000000</td>\n",
              "      <td>0.767250</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>max</th>\n",
              "      <td>9.000000</td>\n",
              "      <td>3122.500000</td>\n",
              "      <td>361.150000</td>\n",
              "      <td>1.480000</td>\n",
              "      <td>18.600000</td>\n",
              "      <td>84.400000</td>\n",
              "      <td>8.094000</td>\n",
              "      <td>2.000000</td>\n",
              "      <td>1.000000</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "            Facies        Depth  ...         NM_M       RELPOS\n",
              "count  3232.000000  3232.000000  ...  3232.000000  3232.000000\n",
              "mean      4.422030  2875.824567  ...     1.498453     0.520287\n",
              "std       2.504243   131.006274  ...     0.500075     0.286792\n",
              "min       1.000000  2573.500000  ...     1.000000     0.010000\n",
              "25%       2.000000  2791.000000  ...     1.000000     0.273000\n",
              "50%       4.000000  2893.500000  ...     1.000000     0.526000\n",
              "75%       6.000000  2980.000000  ...     2.000000     0.767250\n",
              "max       9.000000  3122.500000  ...     2.000000     1.000000\n",
              "\n",
              "[8 rows x 9 columns]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 6
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "xYclPvD4uVfk",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 466
        },
        "outputId": "4ddb67e5-b63b-4345-f87a-cc49360ad921"
      },
      "source": [
        "#count the number of unique entries for each facies, sort them by facies number (instead of by number of entries)\n",
        "#计算每个相的唯一条目数，然后按相数（而不是条目数）对它们进行排序\n",
        "facies_counts = training_data['Facies'].value_counts().sort_index()\n",
        "#use facies labels to index each count\n",
        "#使用相标签索引每个计数\n",
        "facies_counts.index = facies_labels\n",
        "\n",
        "facies_counts.plot(kind='bar',color=facies_colors, \n",
        "                   title='Distribution of Training Data by Facies')\n",
        "facies_counts"
      ],
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "SS      259\n",
              "CSiS    738\n",
              "FSiS    615\n",
              "SiSh    184\n",
              "MS      217\n",
              "WS      462\n",
              "D        98\n",
              "PS      498\n",
              "BS      161\n",
              "Name: Facies, dtype: int64"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 7
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "QtWLNJ9huaPn",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 288
        },
        "outputId": "75529d8b-5a65-4084-f8f3-ac5ab2228a18"
      },
      "source": [
        "correct_facies_labels = training_data['Facies'].values\n",
        "\n",
        "feature_vectors = training_data.drop(['Formation', 'Well Name', 'Depth','Facies','FaciesLabels'], axis=1)\n",
        "feature_vectors.describe()"
      ],
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>GR</th>\n",
              "      <th>ILD_log10</th>\n",
              "      <th>DeltaPHI</th>\n",
              "      <th>PHIND</th>\n",
              "      <th>PE</th>\n",
              "      <th>NM_M</th>\n",
              "      <th>RELPOS</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>count</th>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "      <td>3232.000000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>mean</th>\n",
              "      <td>66.135769</td>\n",
              "      <td>0.642719</td>\n",
              "      <td>3.559642</td>\n",
              "      <td>13.483213</td>\n",
              "      <td>3.725014</td>\n",
              "      <td>1.498453</td>\n",
              "      <td>0.520287</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>std</th>\n",
              "      <td>30.854826</td>\n",
              "      <td>0.241845</td>\n",
              "      <td>5.228948</td>\n",
              "      <td>7.698980</td>\n",
              "      <td>0.896152</td>\n",
              "      <td>0.500075</td>\n",
              "      <td>0.286792</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>min</th>\n",
              "      <td>13.250000</td>\n",
              "      <td>-0.025949</td>\n",
              "      <td>-21.832000</td>\n",
              "      <td>0.550000</td>\n",
              "      <td>0.200000</td>\n",
              "      <td>1.000000</td>\n",
              "      <td>0.010000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>25%</th>\n",
              "      <td>46.918750</td>\n",
              "      <td>0.492750</td>\n",
              "      <td>1.163750</td>\n",
              "      <td>8.346750</td>\n",
              "      <td>3.100000</td>\n",
              "      <td>1.000000</td>\n",
              "      <td>0.273000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>50%</th>\n",
              "      <td>65.721500</td>\n",
              "      <td>0.624437</td>\n",
              "      <td>3.500000</td>\n",
              "      <td>12.150000</td>\n",
              "      <td>3.551500</td>\n",
              "      <td>1.000000</td>\n",
              "      <td>0.526000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>75%</th>\n",
              "      <td>79.626250</td>\n",
              "      <td>0.812735</td>\n",
              "      <td>6.432500</td>\n",
              "      <td>16.453750</td>\n",
              "      <td>4.300000</td>\n",
              "      <td>2.000000</td>\n",
              "      <td>0.767250</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>max</th>\n",
              "      <td>361.150000</td>\n",
              "      <td>1.480000</td>\n",
              "      <td>18.600000</td>\n",
              "      <td>84.400000</td>\n",
              "      <td>8.094000</td>\n",
              "      <td>2.000000</td>\n",
              "      <td>1.000000</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "                GR    ILD_log10  ...         NM_M       RELPOS\n",
              "count  3232.000000  3232.000000  ...  3232.000000  3232.000000\n",
              "mean     66.135769     0.642719  ...     1.498453     0.520287\n",
              "std      30.854826     0.241845  ...     0.500075     0.286792\n",
              "min      13.250000    -0.025949  ...     1.000000     0.010000\n",
              "25%      46.918750     0.492750  ...     1.000000     0.273000\n",
              "50%      65.721500     0.624437  ...     1.000000     0.526000\n",
              "75%      79.626250     0.812735  ...     2.000000     0.767250\n",
              "max     361.150000     1.480000  ...     2.000000     1.000000\n",
              "\n",
              "[8 rows x 7 columns]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 8
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-YpX8bElsI7K",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "from sklearn.model_selection import train_test_split\n",
        "\n",
        "X_train, X_test, y_train, y_test = train_test_split(\n",
        "        feature_vectors, correct_facies_labels, test_size=0.2, random_state=42)"
      ],
      "execution_count": 9,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xnM6c_Q-vhfi",
        "colab_type": "text"
      },
      "source": [
        "#smote"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "aJqYaIDDT2xz",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 400
        },
        "outputId": "6691490d-2eb2-4769-8fe4-645eab969780"
      },
      "source": [
        "from imblearn.over_sampling import SMOTE\n",
        "from collections import Counter\n",
        "sm = SMOTE(random_state=123)\n",
        "X_train_sm, y_train_sm = sm.fit_sample(X_train, y_train)\n",
        "\n",
        "train_x = pd.DataFrame(X_train_sm)\n",
        "train_y = pd.DataFrame(y_train_sm)\n",
        "print(Counter(y_train_sm))"
      ],
      "execution_count": 17,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Counter({5: 585, 2: 585, 9: 585, 3: 585, 8: 585, 1: 585, 6: 585, 4: 585, 7: 585})\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/sklearn/externals/six.py:31: FutureWarning: The module is deprecated in version 0.21 and will be removed in version 0.23 since we've dropped support for Python 2.7. Please rely on the official version of six (https://pypi.org/project/six/).\n",
            "  \"(https://pypi.org/project/six/).\", FutureWarning)\n",
            "/usr/local/lib/python3.6/dist-packages/sklearn/utils/deprecation.py:144: FutureWarning: The sklearn.neighbors.base module is  deprecated in version 0.22 and will be removed in version 0.24. The corresponding classes / functions should instead be imported from sklearn.neighbors. Anything that cannot be imported from sklearn.neighbors is now part of the private API.\n",
            "  warnings.warn(message, FutureWarning)\n",
            "/usr/local/lib/python3.6/dist-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function safe_indexing is deprecated; safe_indexing is deprecated in version 0.22 and will be removed in version 0.24.\n",
            "  warnings.warn(msg, category=FutureWarning)\n",
            "/usr/local/lib/python3.6/dist-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function safe_indexing is deprecated; safe_indexing is deprecated in version 0.22 and will be removed in version 0.24.\n",
            "  warnings.warn(msg, category=FutureWarning)\n",
            "/usr/local/lib/python3.6/dist-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function safe_indexing is deprecated; safe_indexing is deprecated in version 0.22 and will be removed in version 0.24.\n",
            "  warnings.warn(msg, category=FutureWarning)\n",
            "/usr/local/lib/python3.6/dist-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function safe_indexing is deprecated; safe_indexing is deprecated in version 0.22 and will be removed in version 0.24.\n",
            "  warnings.warn(msg, category=FutureWarning)\n",
            "/usr/local/lib/python3.6/dist-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function safe_indexing is deprecated; safe_indexing is deprecated in version 0.22 and will be removed in version 0.24.\n",
            "  warnings.warn(msg, category=FutureWarning)\n",
            "/usr/local/lib/python3.6/dist-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function safe_indexing is deprecated; safe_indexing is deprecated in version 0.22 and will be removed in version 0.24.\n",
            "  warnings.warn(msg, category=FutureWarning)\n",
            "/usr/local/lib/python3.6/dist-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function safe_indexing is deprecated; safe_indexing is deprecated in version 0.22 and will be removed in version 0.24.\n",
            "  warnings.warn(msg, category=FutureWarning)\n",
            "/usr/local/lib/python3.6/dist-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function safe_indexing is deprecated; safe_indexing is deprecated in version 0.22 and will be removed in version 0.24.\n",
            "  warnings.warn(msg, category=FutureWarning)\n"
          ],
          "name": "stderr"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NZtG8GLTsKNc",
        "colab_type": "text"
      },
      "source": [
        "#PCA降维"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "harMDRTgsU4N",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 281
        },
        "outputId": "4ed61d50-597e-41aa-84e3-af6e78265f00"
      },
      "source": [
        "import numpy as np\n",
        "from sklearn.datasets import load_iris\n",
        "from sklearn.decomposition import PCA\n",
        "import matplotlib.pyplot as plt\n",
        "X = feature_vectors\n",
        "Y = correct_facies_labels\n",
        "sklearn_pca = PCA(n_components=5)#降维\n",
        "data_2d2 = sklearn_pca.fit_transform(X)\n",
        "plt.subplot(122)\n",
        "plt.title(\"sklearn_PCA\")\n",
        "plt.scatter(data_2d2[:, 0], data_2d2[:, 1], c = Y)\n",
        "plt.show()"
      ],
      "execution_count": 14,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "f4YxHL31sZC4",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "from sklearn.model_selection import train_test_split\n",
        "X_train_PCA,X_test_PCA,y_train_PCA,y_test_PCA=train_test_split(data_2d2,correct_facies_labels,test_size=0.2,random_state=42)"
      ],
      "execution_count": 15,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kJqVkh7Csa7U",
        "colab_type": "text"
      },
      "source": [
        "##PCA的随机森林"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "DbrN8__ctdFX",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 656
        },
        "outputId": "79a9b034-d0e7-4ee5-f9e2-9a26e8a3d8c9"
      },
      "source": [
        "#降到五维效果较好\n",
        "from sklearn.ensemble import RandomForestClassifier\n",
        "from sklearn import metrics\n",
        "\n",
        "rfmodel = RandomForestClassifier()\n",
        "rfmodel.fit(X_train_PCA,y_train_PCA)\n",
        "print('model')\n",
        "print(rfmodel)\n",
        "\n",
        "ypredrf1 = rfmodel.predict(X_test_PCA)\n",
        "print('confusion matrix')\n",
        "print(metrics.confusion_matrix(y_test_PCA, ypredrf1))\n",
        "print('classification report')\n",
        "print(metrics.classification_report(y_test_PCA, ypredrf1))\n",
        "print('Accuracy : %f' % (metrics.accuracy_score(y_test_PCA, ypredrf1)))"
      ],
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "model\n",
            "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,\n",
            "                       criterion='gini', max_depth=None, max_features='auto',\n",
            "                       max_leaf_nodes=None, max_samples=None,\n",
            "                       min_impurity_decrease=0.0, min_impurity_split=None,\n",
            "                       min_samples_leaf=1, min_samples_split=2,\n",
            "                       min_weight_fraction_leaf=0.0, n_estimators=100,\n",
            "                       n_jobs=None, oob_score=False, random_state=None,\n",
            "                       verbose=0, warm_start=False)\n",
            "confusion matrix\n",
            "[[ 29  12   5   0   0   0   0   0   0]\n",
            " [  6 107  38   0   2   0   0   0   0]\n",
            " [  5  33  85   0   0   1   1   1   0]\n",
            " [  0   1   1  19   2   4   0   1   0]\n",
            " [  0   1   2   4  17  15   1   7   0]\n",
            " [  0   0   0   8   7  65   0  20   0]\n",
            " [  0   0   1   1   1   1   6  11   1]\n",
            " [  0   0   3   6   2  13   0  66   4]\n",
            " [  0   0   0   0   0   0   0   1  30]]\n",
            "classification report\n",
            "              precision    recall  f1-score   support\n",
            "\n",
            "           1       0.72      0.63      0.67        46\n",
            "           2       0.69      0.70      0.70       153\n",
            "           3       0.63      0.67      0.65       126\n",
            "           4       0.50      0.68      0.58        28\n",
            "           5       0.55      0.36      0.44        47\n",
            "           6       0.66      0.65      0.65       100\n",
            "           7       0.75      0.27      0.40        22\n",
            "           8       0.62      0.70      0.66        94\n",
            "           9       0.86      0.97      0.91        31\n",
            "\n",
            "    accuracy                           0.66       647\n",
            "   macro avg       0.66      0.63      0.63       647\n",
            "weighted avg       0.66      0.66      0.65       647\n",
            "\n",
            "Accuracy : 0.655332\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "irqsbQUQtinD",
        "colab_type": "text"
      },
      "source": [
        "##PCA的xgboost"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "InxbbzY7tfXO",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 312
        },
        "outputId": "ad67e6f0-190c-4f3d-b9d4-7b87201f7858"
      },
      "source": [
        "#降到六维效果较好\n",
        "from xgboost import plot_importance\n",
        "from matplotlib import pyplot as plt\n",
        "\n",
        "import xgboost as xgb\n",
        "from numpy import loadtxt\n",
        "from sklearn.model_selection import train_test_split\n",
        "from sklearn.metrics import accuracy_score\n",
        "\n",
        "params ={'learning_rate': 0.4,\n",
        "          'max_depth': 20,                # 构建树的深度，越大越容易过拟合\n",
        "          'num_boost_round':2000,\n",
        "          'objective': 'multi:softprob', # 多分类的问题\n",
        "          'random_state': 7,\n",
        "          'silent':0,\n",
        "          'num_class':10,                 # 类别数，与 multisoftmax 并用\n",
        "          'eta':0.8                      #为了防止过拟合，更新过程中用到的收缩步长。eta通过缩减特征 的权重使提升计算过程更加保守。缺省值为0.3，取值范围为：[0,1]\n",
        "        }\n",
        "model = xgb.train(params,xgb.DMatrix(X_train_PCA, y_train_PCA))\n",
        "y_pred=model.predict(xgb.DMatrix(X_test_PCA))\n",
        "\n",
        "model.save_model('testXGboostClass.model')  # 保存训练模型\n",
        "\n",
        "yprob = np.argmax(y_pred, axis=1)  # return the index of the biggest pro\n",
        "\n",
        "predictions = [round(value) for value in yprob]\n",
        "\n",
        "# evaluate predictions\n",
        "accuracy = accuracy_score(y_test_PCA, predictions)\n",
        "print(\"Accuracy: %.2f%%\" % (accuracy * 100.0))\n",
        "\n",
        "# 显示重要特征\n",
        "plot_importance(model)\n",
        "plt.show()"
      ],
      "execution_count": 18,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Accuracy: 63.06%\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "a-LZwlgpvzQw",
        "colab_type": "text"
      },
      "source": [
        "##PCA的knn"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "F07fqNykwM6b",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import sys\n",
        "sys.path.append('/content/drive/My Drive/Colab Notebooks/Machine-Learning-From-Scratch-master')"
      ],
      "execution_count": 19,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FBMA7f24vy1N",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 325
        },
        "outputId": "0b06d37f-716f-4ae5-a98e-32196c882a62"
      },
      "source": [
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "from sklearn import datasets\n",
        "\n",
        "from utils import train_test_split, normalize, accuracy_score\n",
        "from utils import euclidean_distance, Plot\n",
        "class KNN():\n",
        "\n",
        "    def __init__(self,k=5):\n",
        "\n",
        "        self.k = k\n",
        "    def predict(self, X_test, X_train, y_train):\n",
        "\n",
        "        y_predict = np.zeros(X_test.shape[0])\n",
        "\n",
        "        for i in range(X_test.shape[0]):\n",
        "\n",
        "            distances = np.zeros((X_train.shape[0], 2)) #测试的数据和训练的各个数据的欧式距离\n",
        "\n",
        "            for j in range(X_train.shape[0]):\n",
        "                dis = euclidean_distance(X_test[i], X_train[j]) #计算欧式距离\n",
        "                label = y_train[j] #测试集到的每个训练集的数据的分类标签\n",
        "                distances[j] = [dis, label]\n",
        "\n",
        "                # argsort()得到测试集到训练的各个数据的欧式距离从小到大排列并且得到序列，然后再取前k个.\n",
        "                k_nearest_neighbors = distances[distances[:, 0].argsort()][:self.k]\n",
        "\n",
        "                #利用np.bincount统计k个近邻里面各类别出现的次数\n",
        "                counts = np.bincount(k_nearest_neighbors[:, 1].astype('int'))\n",
        "\n",
        "                #得出每个测试数据k个近邻里面各类别出现的次数最多的类别\n",
        "                testLabel = counts.argmax()\n",
        "                y_predict[i] = testLabel\n",
        "\n",
        "        return y_predict\n",
        "\n",
        "def run():\n",
        "    #初始化knn\n",
        "    model = KNN(k=5)\n",
        "    y_pred = model.predict(X_test_PCA, X_train_PCA, y_train_PCA)\n",
        "\n",
        "    accuracy = accuracy_score(y_test_PCA, y_pred)\n",
        "\n",
        "    print(\"Accuracy:\", accuracy)\n",
        "\n",
        "    # 用图画出测试集的分类情况\n",
        "    Plot().plot_in_2d(X_test_PCA, y_pred, title=\"KNN\", accuracy=accuracy)\n",
        "\n",
        "\n",
        "if __name__ == \"__main__\":\n",
        "    run()"
      ],
      "execution_count": 20,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Accuracy: 0.5100463678516228\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8GKtOcsHy6sB",
        "colab_type": "text"
      },
      "source": [
        "#LDA降维"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5mGMcuvWy9rQ",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 281
        },
        "outputId": "597338d0-bdf9-4148-8a0c-a30468ec4fd5"
      },
      "source": [
        "import numpy as np\n",
        "from sklearn.discriminant_analysis import LinearDiscriminantAnalysis\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "def lda(data, target, n_dim):\n",
        "\n",
        "    clusters = np.unique(target)\n",
        "\n",
        "    if n_dim > len(clusters)-1:\n",
        "        print(\"K is too much\")\n",
        "        print(\"please input again\")\n",
        "        exit(0)\n",
        "\n",
        "    #within_class scatter matrix\n",
        "    Sw = np.zeros((data.shape[1],data.shape[1]))\n",
        "    for i in clusters:\n",
        "        datai = data[target == i]\n",
        "        datai = datai-datai.mean(0)\n",
        "        Swi = np.mat(datai).T*np.mat(datai)\n",
        "        Sw += Swi\n",
        "\n",
        "    #between_class scatter matrix\n",
        "    SB = np.zeros((data.shape[1],data.shape[1]))\n",
        "    u = data.mean(0)  #所有样本的平均值\n",
        "    for i in clusters:\n",
        "        Ni = data[target == i].shape[0]\n",
        "        ui = data[target == i].mean(0)  #某个类别的平均值\n",
        "        SBi = Ni*np.mat(ui - u).T*np.mat(ui - u)\n",
        "        SB += SBi\n",
        "    S = np.linalg.inv(Sw)*SB\n",
        "    eigVals,eigVects = np.linalg.eig(S)  #求特征值，特征向量\n",
        "    eigValInd = np.argsort(eigVals)\n",
        "    eigValInd = eigValInd[:(-n_dim-1):-1]\n",
        "    w = eigVects[:,eigValInd]\n",
        "    data_ndim = np.dot(data, w)\n",
        "\n",
        "    return data_ndim\n",
        "\n",
        "if __name__ == '__main__':\n",
        "    X=feature_vectors\n",
        "    Y=correct_facies_labels\n",
        "    data_1 = lda(X, Y, 5)#自己根据数学原理实现LDA\n",
        "\n",
        "    data_2 = LinearDiscriminantAnalysis(n_components=6).fit_transform(X, Y)#直接调sklearn\n",
        "\n",
        "\n",
        "    plt.figure(figsize=(8,4))\n",
        "    plt.subplot(121)\n",
        "    plt.title(\"my_LDA\")\n",
        "    plt.scatter(data_1[:, 0], data_1[:, 1], c = Y)\n",
        "\n",
        "    plt.subplot(122)\n",
        "    plt.title(\"sklearn_LDA\")\n",
        "    plt.scatter(data_2[:, 0], data_2[:, 1], c = Y)\n",
        "    plt.savefig(\"LDA.png\")\n",
        "    plt.show()"
      ],
      "execution_count": 21,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 576x288 with 2 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "RdgUzBWRzd2h",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "from sklearn.model_selection import train_test_split\n",
        "X_train_LDA,X_test_LDA,y_train_LDA,y_test_LDA=train_test_split(data_2,correct_facies_labels,test_size=0.2,random_state=42)"
      ],
      "execution_count": 22,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dz0XHR_Mzh3n",
        "colab_type": "text"
      },
      "source": [
        "##LDA的随机森林"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zWoeshzizlY4",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 656
        },
        "outputId": "39a9be64-6d69-485c-c65c-d4692a463dde"
      },
      "source": [
        "from sklearn.ensemble import RandomForestClassifier\n",
        "from sklearn import metrics\n",
        "\n",
        "rfmodel = RandomForestClassifier()\n",
        "rfmodel.fit(X_train_LDA,y_train_LDA)\n",
        "print('model')\n",
        "print(rfmodel)\n",
        "\n",
        "ypredrf1 = rfmodel.predict(X_test_LDA)\n",
        "print('confusion matrix')\n",
        "print(metrics.confusion_matrix(y_test_LDA, ypredrf1))\n",
        "print('classification report')\n",
        "print(metrics.classification_report(y_test_LDA, ypredrf1))\n",
        "print('Accuracy : %f' % (metrics.accuracy_score(y_test_LDA, ypredrf1)))"
      ],
      "execution_count": 23,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "model\n",
            "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,\n",
            "                       criterion='gini', max_depth=None, max_features='auto',\n",
            "                       max_leaf_nodes=None, max_samples=None,\n",
            "                       min_impurity_decrease=0.0, min_impurity_split=None,\n",
            "                       min_samples_leaf=1, min_samples_split=2,\n",
            "                       min_weight_fraction_leaf=0.0, n_estimators=100,\n",
            "                       n_jobs=None, oob_score=False, random_state=None,\n",
            "                       verbose=0, warm_start=False)\n",
            "confusion matrix\n",
            "[[ 30  15   1   0   0   0   0   0   0]\n",
            " [  6 112  33   1   0   0   0   1   0]\n",
            " [  0  32  91   1   0   1   0   1   0]\n",
            " [  0   0   1  22   2   1   1   1   0]\n",
            " [  0   2   1   4  21  10   0   9   0]\n",
            " [  0   0   0   7   3  74   1  14   1]\n",
            " [  0   0   0   0   0   1  15   5   1]\n",
            " [  0   0   1   9   4  15   3  58   4]\n",
            " [  0   0   0   0   0   0   0   0  31]]\n",
            "classification report\n",
            "              precision    recall  f1-score   support\n",
            "\n",
            "           1       0.83      0.65      0.73        46\n",
            "           2       0.70      0.73      0.71       153\n",
            "           3       0.71      0.72      0.72       126\n",
            "           4       0.50      0.79      0.61        28\n",
            "           5       0.70      0.45      0.55        47\n",
            "           6       0.73      0.74      0.73       100\n",
            "           7       0.75      0.68      0.71        22\n",
            "           8       0.65      0.62      0.63        94\n",
            "           9       0.84      1.00      0.91        31\n",
            "\n",
            "    accuracy                           0.70       647\n",
            "   macro avg       0.71      0.71      0.70       647\n",
            "weighted avg       0.71      0.70      0.70       647\n",
            "\n",
            "Accuracy : 0.701700\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_p7V3pE-08yH",
        "colab_type": "text"
      },
      "source": [
        "##LDA的xgboost"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "rgW1u8mh1BhI",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 312
        },
        "outputId": "24a6b7dc-f877-470a-f383-46c08b01732a"
      },
      "source": [
        "from xgboost import plot_importance\n",
        "from matplotlib import pyplot as plt\n",
        "\n",
        "import xgboost as xgb\n",
        "from numpy import loadtxt\n",
        "from sklearn.model_selection import train_test_split\n",
        "from sklearn.metrics import accuracy_score\n",
        "\n",
        "params ={'learning_rate': 0.4,\n",
        "          'max_depth': 20,                # 构建树的深度，越大越容易过拟合\n",
        "          'num_boost_round':2000,\n",
        "          'objective': 'multi:softprob', # 多分类的问题\n",
        "          'random_state': 7,\n",
        "          'silent':0,\n",
        "          'num_class':10,                 # 类别数，与 multisoftmax 并用\n",
        "          'eta':0.8                      #为了防止过拟合，更新过程中用到的收缩步长。eta通过缩减特征 的权重使提升计算过程更加保守。缺省值为0.3，取值范围为：[0,1]\n",
        "        }\n",
        "model = xgb.train(params,xgb.DMatrix(X_train_LDA, y_train_LDA))\n",
        "y_pred=model.predict(xgb.DMatrix(X_test_LDA))\n",
        "\n",
        "model.save_model('testXGboostClass.model')  # 保存训练模型\n",
        "\n",
        "yprob = np.argmax(y_pred, axis=1)  # return the index of the biggest pro\n",
        "\n",
        "predictions = [round(value) for value in yprob]\n",
        "\n",
        "# evaluate predictions\n",
        "accuracy = accuracy_score(y_test_LDA, predictions)\n",
        "print(\"Accuracy: %.2f%%\" % (accuracy * 100.0))\n",
        "\n",
        "# 显示重要特征\n",
        "plot_importance(model)\n",
        "plt.show()"
      ],
      "execution_count": 24,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Accuracy: 66.46%\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAEWCAYAAABliCz2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3de3xU9Z3/8dcnRFGTakjDPVDAcE24qFSx1TSiERHv67KguwTRelul7lqFruuF7q5A1Sr+tGURrVTrpSqCvQi4SqTdahVULoJYLVkhhPtFkyIm4fP7Yw5xEkISIJOZzHk/H495cM73nDPn+8kJ7znnO2cm5u6IiEjyS4l3B0REpGUo8EVEQkKBLyISEgp8EZGQUOCLiISEAl9EJCQU+CJ1mNm/mdnsePdDpLmZ7sOX5mRmJUBHoDqquY+7bzzC57zG3f/nyHrX+pjZPUCOu/9jvPsirZ/O8CUWLnT39KjHYYd9czCz1Hju/3C11n5L4lLgS4swsxPM7HEzKzOzUjP7TzNrEyw70czeMLPtZrbNzH5lZhnBsqeA7sBvzKzczG43swIz21Dn+UvM7Jxg+h4ze9HMnjazz4HxDe2/nr7eY2ZPB9M9zMzN7CozW29mO83sejP7tpmtMLNdZvZI1Lbjzex/zewRM9ttZh+Z2dlRy7uY2StmtsPMPjGz79fZb3S/rwf+DfiHoPblwXpXmdkaM/vCzP5qZtdFPUeBmW0ws1vNbEtQ71VRy481swfM7P+C/v3RzI4Nlg0zsz8FNS03s4LDOtiSsBT40lKeBKqAHOAk4FzgmmCZAVOBLkB/oBtwD4C7/xPwGV9fNfykifu7GHgRyAB+1cj+m+I0oDfwD8BDwB3AOUAuMNrMvldn3U+BLOBuYK6ZZQbLngM2BLVeDtxrZsMP0u/HgXuB54PaBwfrbAEuAI4HrgIeNLOTo56jE3AC0BW4GnjUzNoFy+4HTgG+A2QCtwP7zKwr8DvgP4P2HwIvmVn7Q/gZSYJT4EsszAvOEneZ2Twz6wicD9zi7hXuvgV4EBgD4O6fuPtr7r7X3bcCPwW+d/Cnb5K33H2eu+8jEowH3X8T/Ye7f+nui4AK4Fl33+LupcAfiLyI7LcFeMjdK939eWAtMMrMugHfBSYFz/UBMBsYV1+/3X1PfR1x99+5+6ce8SawCDgzapVK4MfB/n8PlAN9zSwFmAD8wN1L3b3a3f/k7nuBfwR+7+6/D/b9GrA0+LlJktAYocTCJdFvsJrZqcBRQJmZ7W9OAdYHyzsCM4iE1jeCZTuPsA/ro6a/1dD+m2hz1PSeeubTo+ZLvfbdEP9H5Iy+C7DD3b+os2zoQfpdLzMbSeTKoQ+ROo4DVkatst3dq6Lm/xb0Lws4hsjVR13fAv7ezC6MajsKWNxYf6T1UOBLS1gP7AWy6gTRfvcCDgx09x1mdgnwSNTyureSVRAJOQCCsfi6Qw/R2zS2/+bW1cwsKvS7A68AG4FMM/tGVOh3B0qjtq1ba615M2sLvETkqmC+u1ea2Twiw2KN2QZ8CZwILK+zbD3wlLt//4CtJGloSEdizt3LiAw7PGBmx5tZSvBG7f5hm28QGXbYHYwl31bnKTYDvaLmPwaOMbNRZnYU8O9A2yPYf3PrAEw0s6PM7O+JvC/xe3dfD/wJmGpmx5jZICJj7E838FybgR7BcAzA0URq3QpUBWf75zalU8Hw1hPAT4M3j9uY2enBi8jTwIVmNiJoPyZ4Azj70MuXRKXAl5YyjkhYrSYyXPMi0DlYNgU4GdhN5I3DuXW2nQr8e/CewA/dfTdwI5Hx71IiZ/wbaFhD+29ufybyBu824L+Ay919e7BsLNCDyNn+y8DdjXy+4IXg3+1m9l5wZTAR+DWROq4gcvXQVD8kMvzzLrADmA6kBC9GFxO5K2grkTP+21BGJBV98EqkGZnZeCIfEjsj3n0RqUuv3iIiIaHAFxEJCQ3piIiEhM7wRURCImHvw8/IyPCcnJx4d6NZVFRUkJaWFu9uHLFkqQNUSyJKljogvrUsW7Zsm7vX+5UYCRv4HTt2ZOnSpfHuRrMoLi6moKAg3t04YslSB6iWRJQsdUB8azGz/zvYMg3piIiEhAJfRCQkFPgiIiGhwBcRCQkFvohISCjwRURCQoEvIhISCnwRkZBQ4IuIhIQCX0QkJBT4IiIhocAXEQkJBb6ISEgo8EVEQkKBLyISEgp8EZGQUOCLiISEAl9EJCQU+CIiIaHAFxEJCQW+iEhIKPBFREJCgS8iEhIKfBGRkFDgi4iEhAJfRCRGJkyYQIcOHcjLy6tpu+222+jXrx+DBg3i0ksvZdeuXTXLpk6dSk5ODn379mXhwoUAfPnll5x66qkMHjyY3Nxc7r777sPuj7n74VfT0BObTQRuAI4H0oF1waK57v7jxrbv3ivHU0bPiEnfWtqtA6t4YGVqvLtxxJKlDlAtiShZ6oBILTdfeTFLliwhPT2dcePGsWrVKgAWLVrE8OHDSU1NZdKkSQBMnz6d1atXM3bsWN555x02btzIOeecw8cff0xKSgoVFRWkp6dTWVnJGWecwYwZMxg2bFi9+zazZe4+tL5lsTzDvxEoBK4E/uDuQ4JHo2EvIpIM8vPzyczMrNV27rnnkpoaeWEbNmwYGzZsAGD+/PmMGTOGtm3b0rNnT3JycnjnnXcwM9LT0wGorKyksrISMzus/sQk8M1sJtALeBU4KRb7EBFp7Z544glGjhwJQGlpKd26datZlp2dTWlpKQDV1dUMGTKEDh06UFhYyGmnnXZY+4vJ9ZO7X29m5wFnAXnAv5vZcmAj8EN3/7C+7czsWuBagKys9tw1sCoW3WtxHY+NXOK1dslSB6iWRJQsdUCkluLiYgA2bdpERUVFzfx+Tz/9NLt27aJr164UFxdTWlrKmjVratYrKyvjww8/JCsrC4CHHnqI8vJy7rzzTvr160fPnj0PuV8tMWD2HvAtdy83s/OBeUDv+lZ091nALIiM4SfTeF4y1JIsdYBqSUTJUgdEahldUABASUkJaWlpFATzAE8++SQffvghr7/+OscddxwAb731FkDNelOnTuXcc8/l9NNPr/Xc7733Htu3b+eqq6465H7F/C4dd//c3cuD6d8DR5lZVqz3KyKSiBYsWMBPfvITXnnllZqwB7jooot47rnn2Lt3L+vWreMvf/kLp556Klu3bq25k2fPnj289tpr9OvX77D2HfOXUzPrBGx2dzezU4m8yGyP9X5FROJt7NixFBcXs23bNrKzs5kyZQpTp05l7969FBYWApE3bmfOnElubi6jR49mwIABpKam8uijj9KmTRvKysooKiqiurqaffv2MXr0aC644ILD6k8sb8ssAYYCY4jcnlkF7AH+1d3/1Nj2ffv29bVr18akby2tuLi41uVca5UsdYBqSUTJUgfEt5aGbsuM2Rm+u/cIJh8JHiIiEkf6pK2ISEgo8EVEQkKBLyISEgp8EZGQUOCLiISEAl9EJCQU+CIiIaHAFxEJCQW+iEhIKPBFREJCgS8iEhIKfBGRkFDgi4iEhAJfRCQkFPgiIiGhwBcRCQkFvohISCjwRURCQoEvIhISCnwRkZBQ4IuIhIQCX0SkGU2YMIFLL72UvLy8mrYXXniB3NxcUlJSWLp0aU37V199xVVXXcXAgQMZPHgwxcXFNcuWLVvGwIEDycnJYeLEibj7Efct9YifoQFmNhG4AXjP3a80s28DbwFj3P3FhrbdU1lNj8m/i2X3WsytA6sYnwS1JEsdoFoSUWuvo2TaKADGjx/PsGHDePjhh2uW5eXlMXfuXK677rpa2zz22GMArFy5ki1btjBy5EjeffddUlJSuOGGG3jsscc47bTTOP/881mwYAEjR448oj7G+gz/RqAwCPs2wHRgUYz3KSISN/n5+Rx//PG12vr370/fvn0PWHf16tUMHz4cgA4dOpCRkcHSpUspKyvj888/Z9iwYZgZ48aNY968eUfct5gFvpnNBHoBr5rZvwA3Ay8BW2K1TxGR1mTw4MG88sorVFVVsW7dOpYtW8b69espLS0lOzu7Zr3s7GxKS0uPeH8xG9Jx9+vN7DzgLKAt8Eww/e2DbWNm1wLXAmRlteeugVWx6l6L6nhs5HK1tUuWOkC1JKLWXkf0+HtFRQUVFRW12gB27drFsmXLKC8vB+DEE0/ktddeo1+/fnTs2JF+/fqxZs0atm3bxs6dO2u2X7FiBdu3bz/g+Q5VTMfwozwETHL3fWZ20JXcfRYwC6B7rxx/YGVLdS+2bh1YRTLUkix1gGpJRK29jpIrC2qmN23aRFpaGgUFBbXWycjI4JRTTmHo0KE1bWeffXbN9He+8x0uu+wy2rVrx4MPPlizfVlZGYMGDTrg+Q5VS92lMxR4zsxKgMuBn5nZJS20bxGRhPS3v/2NiooKAF577TVSU1MZMGAAnTt35vjjj+ftt9/G3fnlL3/JxRdffMT7a5GXU3fvuX/azJ4EfuvuR/4OhIhIghk7diyLFi3i888/Jzs7mylTppCZmcnNN9/M1q1bGTVqFEOGDGHhwoVs2bKFESNGkJKSQteuXXnqqadqnudnP/sZ48ePZ8+ePYwcOfKI79ABwN1j9gBKgKw6bU8Clze2bZ8+fTxZLF68ON5daBbJUoe7aklEyVKHe3xrAZb6QXI1pmf47t6jnrbxsdyniIjUT5+0FREJCQW+iEhIKPBFREJCgS8iEhIKfBGRkFDgi4iEhAJfRCQkFPgiIiGhwBcRCQkFvohISCjwRURCQoEvIhISCnwRkZBQ4IuIhIQCX0QkJBT4IiIhocAXEQkJBb6ISEgo8EVEQkKBLyISEgp8EZGQUOCLiAATJkygQ4cO5OXl1bS98MIL5ObmkpKSwtKlS2vat2/fzllnnUV6ejo33XRTred5/vnnufrqq8nNzWXSpEkt1v+mMHdvfCWzE4EN7r7XzAqAQcAv3X1XA9tMBG4A+gErAQO+AG5w9+WN7bN7rxxPGT2jSUUkulsHVvHAytR4d+OIJUsdoFoSUbzqKJk2CoAlS5aQnp7OuHHjWLVqFQBr1qwhJSWF6667jvvvv5+hQ4cCUFFRwfvvv8+qVatYtWoVjzzyCBB5ITjppJN4+OGHueSSSygqKmLcuHGcffbZLVaPmS1z96H1LWvqGf5LQLWZ5QCzgG7AM41scyNQCHwX+J67DwT+I9heRCSh5Ofnk5mZWautf//+9O3b94B109LSOOOMMzjmmGNqtf/1r3+ld+/eZGRkAHDOOefw0ksvxa7Th6ipgb/P3auAS4H/5+63AZ0PtrKZzQR6Aa8Cp7n7zmDR20D2EfRXRCRh5eTksHbtWjZt2kRVVRXz5s1j/fr18e5WjaYGfqWZjQWKgN8GbUcdbGV3vx7YCJzl7g9GLbqayIuAiEjSadeuHT//+c+ZMmUKZ555Jj169KBNmzbx7laNpg6YXQVcD/yXu68zs57AU4eyIzM7i0jgn9HAOtcC1wJkZbXnroFVh7KLhNXx2Mj4ZGuXLHWAaklE8aqjuLi4ZnrTpk1UVFTUagPYtWsXy5Yto7y8vFb7Rx99RGlpaa31v/GNb3DfffeRnp7Ob37zG4455pgDni9emhT47r7azCYB3YP5dcD0pu7EzAYBs4GR7r69gf3MIhjj794rx5PhjSjQm2qJSLUknri9aXtlwdfTJSWkpaVRUFBQa52MjAxOOeWUmjdto9cvLy+vtf6WLVtYvXo1gwcP5pZbbuHXv/41ffr0iWEFTdekn66ZXQjcDxwN9DSzIcCP3f2iJmzbHZgL/JO7f3wknRURiZWxY8dSXFzMtm3byM7OZsqUKWRmZnLzzTezdetWRo0axZAhQ1i4cCEAPXr04PPPP+err75i3rx5LFq0iAEDBvCDH/yAt956i+OOO4677rorYcIeAHdv9AEsA04A3o9qW9XINiVAFpEz+53AB8FjaVP22adPH08WixcvjncXmkWy1OGuWhJRstThHt9aGsrYpl4/Vbr7bjOLbtvXyAtJj2DymuAhIiJx1NTA/9DMrgDamFlvYCLwp9h1S0REmltTb8u8GcgF9hL5wNVu4JZYdUpERJpfo2f4ZtYG+J27nwXcEfsuiYhILDR6hu/u1cA+MzuhBfojIiIx0tQx/HJgpZm9BlTsb3T3iTHplYiINLumBv7c4CEiIq1UUz9pOyfWHRERkdhq6idt1wEHfHG+u/dq9h6JiEhMNHVIJ/oLJI4B/h7IPMi6IiKSgJp0H767b496lLr7Q8CoGPdNRESaUVOHdE6Omk0hcsbf+r+eT0QkRJoa2g9ETVcB64DRzd8dERGJlaYG/tXu/tfohuCPoIiISCvR1O/SebGJbSIikqAaPMM3s35EvjTtBDO7LGrR8UTu1hERkVaisSGdvsAFQAZwYVT7F8D3Y9UpERFpfg0GvrvPB+ab2enu/lYL9UlERGKgqW/avm9m/0xkeKdmKMfdJ8SkVyIi0uya+qbtU0AnYATwJpBNZFhHRERaiaYGfo673wlUBF+kNgo4LXbdEhGR5tbUwK8M/t1lZnnACUCH2HRJRERioamBP8vM2gF3Aq8Aq4GfxKxXIiIxNmHCBDp06EBeXl5N2wsvvEBubi4pKSksXbq01vpTp04lJyeHvn37snDhQgC+/PJLTj31VAYPHkxubi533313i9ZwqJr65Wmz3X2nu7/p7r3cvYO7z2xsOzObaGZrzOxXZvawmX1iZivqfDePiEiLGz9+PAsWLKjVlpeXx9y5c8nPz6/Vvnr1ap577jk+/PBDFixYwI033kh1dTVt27bljTfeYPny5XzwwQcsWLCAt99+uyXLOCRN/fK0jsC9QBd3H2lmA4DT3f3xRja9ETgHGATcDPQmMvb/cxp5D2BPZTU9Jv+uKd1LeLcOrGJ8EtSSLHWAaklELVVHybTIF/3m5+dTUlJSa1n//v3r3Wb+/PmMGTOGtm3b0rNnT3JycnjnnXc4/fTTSU9PB6CyspLKykrMLKb9PxJNHdJ5ElgIdAnmPwZuaWgDM5sJ9AJeBV4GfukRbwMZZtb5sHosItLCSktL6datW818dnY2paWlAFRXVzNkyBA6dOhAYWEhp52WuPezNDXws9z918A+AHevAqob2sDdrwc2AmcBrwHroxZvALoecm9FRBJMmzZt+OCDD9iwYQPvvPMOq1atineXDqqpH7yqMLNvEvyZQzMbBuxu7s6Y2bXAtQBZWe25a2BVc+8iLjoeG7lcbe2SpQ5QLYmopeooLi6umd60aRMVFRW12gB27drFsmXLKC8vB2Dv3r28+eabZGdnA7BixQpOPvnkA7br0aMHjz76KKNGjTpgWSJoauD/K5G7c040s/8F2gOXH8J+SoFuUfPZQVst7j4LmAXQvVeOP7AyOf7Gyq0Dq0iGWpKlDlAtiail6ii5suDr6ZIS0tLSKCgoqLVORkYGp5xyCkOHRv66a/v27bniiit45JFH2LhxI9u3b+f6669nx44dHHXUUWRkZLBnzx7uvPNOJk2aRHp6+gHPmQga+7bM7u7+mbu/Z2bfI/JlagasdffKhrat4xXgJjN7jsibtbvdveywey0icoTGjh1LcXEx27ZtIzs7mylTppCZmcnNN9/M1q1bGTVqFEOGDGHhwoXk5uYyevRoBgwYQGpqKo8++iht2rShrKyMoqIiqqur2bdvH6NHj+aCCy5IyLN7ANz9oA/gvajplxpa9yDblwBZRF4kHgU+BVYCQxvbtk+fPp4sFi9eHO8uNItkqcNdtSSiZKnDPb61AEv9ILna2PVT9P1FvQ7jxaRH1Ow/H+r2IiLSfBq7S8cPMi0iIq1MY2f4g83scyJn+scG0wTz7u7Hx7R3IiLSbBr7AyhtWqojIiISW0394JWIiLRyCnwRkZBQ4IuIhIQCX0QkJBT4IiIhocAXEQkJBb6ISEgo8EVEQkKBLyISEgp8EZGQUOCLiISEAl9EJCQU+CIiIaHAFxEJCQW+iEhIKPBFREJCgS8iEhIKfBGRkFDgi4iEhAJfRJLehAkT6NChA3l5eTVtO3bsoLCwkN69e1NYWMjOnTsB2L17NxdeeCGDBw8mNzeXX/ziFzXbfPbZZ5x77rn079+fAQMGUFJS0tKlHBFz99g9udlE4AagE7Ae2AdUAbe4+x8b2rZ7rxxPGT0jZn1rSbcOrOKBlQ3+vfhWIVnqANWSiGJVR8m0USxZsoT09HTGjRvHqlWrALj99tvJzMxk8uTJTJs2jZ07dzJ9+nTuvfdedu/ezfTp09m6dSt9+/Zl06ZNHH300RQUFHDHHXdQWFhIeXk5KSkpHHfccQfss7i4mIKCgmavpSnMbJm7D61vWazP8G8ECoFuwGB3HwJMAGbHeL8iIjXy8/PJzMys1TZ//nyKiooAKCoqYt68eQCYGV988QXuTnl5OZmZmaSmprJ69WqqqqooLCwEID09vd6wT2QxC3wzmwn0Al4Fvu9fX0qkAbG7rBARaYLNmzfTuXNnADp16sTmzZsBuOmmm1izZg1dunRh4MCBzJgxg5SUFD7++GMyMjK47LLLOOmkk7jtttuorq6OZwmHLGbXge5+vZmdB5zl7tvM7FJgKtABGFXfNmZ2LXAtQFZWe+4aWBWr7rWojsdGLldbu2SpA1RLIopVHcXFxQBs2rSJioqKmvmqqqqaaYDq6mqKi4t58803ycrK4plnnmHjxo1cc801zJ49m+XLl1NcXMysWbPo2LEjU6ZMYfLkyYwadWCclZeX13ruRNFiA3/u/jLwspnlA/8BnFPPOrOAWRAZw0+GcUnQGGsiUi2JJ2Zj+FcWRP4tKSEtLa1mbL1r16707duXzp07U1ZWRpcuXSgoKOC+++5j8uTJnHnmmQA8/vjjtG/fnhEjRvDGG29wxRVXALBx40befvvtesfq4zmG35AWv0vH3ZcAvcwsq6X3LSKy30UXXcScOXMAmDNnDhdffDEA3bt35/XXXwciwz5r166lV69efPvb32bXrl1s3boVgDfeeIMBAwbEp/OHy91j9gBKgCwgh6/vCDoZKN0/f7BHnz59PFksXrw43l1oFslSh7tqSUSxrGPMmDHeqVMnT01N9a5du/rs2bN927ZtPnz4cM/JyfGzzz7bt2/f7u7upaWlXlhY6Hl5eZ6bm+tPPfVUzfMsWrTIBw4c6Hl5eV5UVOR79+5t8VoaAyz1g+RqS10H/h0wzswqgT3APwQdExGJuWeffbbe9v1n8tG6dOnCokWL6l2/sLCQFStWNGvfWlJMA9/dewST04OHiIjEiT5pKyISEgp8EZGQUOCLiISEAl9EJCQU+CIiIaHAFxEJCQW+iEhIKPBFREJCgS8iEhIKfBGRkFDgi4iEhAJfRCQkFPgiIiGhwBcRCQkFvohISCjwRURCQoEvIhISCnwRkZBQ4IuIhIQCX0QkJBT4IiIhocAXkVZjwoQJdOjQgby8vJq2HTt2UFhYSO/evSksLGTnzp0AzJ8/n0GDBjFkyBCGDh3KH//4x5pt5syZQ+/evenduzdz5sxp8Trixdw9Nk9sNhG4AVgNdAFOBu5w9/ubsn33XjmeMnpGTPrW0m4dWMUDK1Pj3Y0jlix1gGpJRI3VUTJtFEuWLCE9PZ1x48axatUqAG6//XYyMzOZPHky06ZNY+fOnUyfPp3y8nLS0tIwM1asWMHo0aP56KOP2LFjB0OHDmXp0qWYGaeccgrLli2jXbt2zVZLcXExBQUFzfZ8h8LMlrn70PqWxfIM/0agkEjoTwSaFPQiIgeTn59PZmZmrbb58+dTVFQEQFFREfPmzQMgPT0dMwOgoqKiZnrhwoUUFhaSmZlJu3btKCwsZMGCBS1YRfzEJPDNbCbQC3gVuNLd3wUqY7EvEQm3zZs307lzZwA6derE5s2ba5a9/PLL9OvXj1GjRvHEE08AUFpaSrdu3WrWyc7OprS0tGU7HScxuQ509+vN7DzgLHff1tTtzOxa4FqArKz23DWwKhbda3Edj41crrZ2yVIHqJZE1FgdxcXFAGzatImKioqa+aqqqpppgOrq6pr5du3aMXPmTJYvX85NN93EAw88wKeffspXX31Vs866deto27Ztrec4UuXl5c36fM0loQb+3H0WMAsiY/jJMC4J4RljbU1US+JpdAz/yoLIvyUlpKWl1YyRd+3alb59+9K5c2fKysro0qXLAePnBQUFzJgxg7y8PMrKymqNsT/77LPk5+c365h7PMfwG6K7dESkVbvoootq7rSZM2cOF198MQCffPIJ+29Kee+999i7dy/f/OY3GTFiBIsWLWLnzp3s3LmTRYsWMWLEiLj1v0W5e0weQAmQFTV/D/DDpm7fp08fTxaLFy+OdxeaRbLU4a5aElFT6hgzZox36tTJU1NTvWvXrj579mzftm2bDx8+3HNycvzss8/27du3u7v7tGnTfMCAAT548GAfNmyY/+EPf6h5nscff9xPPPFEP/HEE/2JJ56ISy2xAiz1g+RqzK8DzawTsBQ4HthnZrcAA9z981jvW0SSy7PPPltv++uvv35A26RJk5g0aVK960+YMIEJEyY0a99ag5gFvrv3iJrNjtV+RESkaTSGLyISEgp8EZGQUOCLiISEAl9EJCQU+CIiIaHAFxEJCQW+iEhIKPBFREJCgS8iEhIKfBGRkFDgi4iEhAJfRCQkFPgiIiGhwBcRCQkFvohISCjwRURCQoEvIhISCnwRkZBQ4IuIhIQCX0QkJBT4IiIhocAXEQkJBb6ISEgo8EVEQkKBLyISEubu8e5DvczsC2BtvPvRTLKAbfHuRDNIljpAtSSiZKkD4lvLt9y9fX0LUlu6J4dgrbsPjXcnmoOZLU2GWpKlDlAtiShZ6oDErUVDOiIiIaHAFxEJiUQO/Fnx7kAzSpZakqUOUC2JKFnqgAStJWHftBURkeaVyGf4IiLSjBT4IiIhkZCBb2bnmdlaM/vEzCbHuz8NMbNuZrbYzFab2Ydm9oOgPdPMXjOzvwT/tgvazcweDmpbYWYnx7eC2sysjZm9b2a/DeZ7mtmfg/4+b2ZHB+1tg/lPguU94tnvuswsw8xeNLOPzGyNmZ3eio/JvwS/W6vM7FkzO6a1HBczezej5PoAAAWxSURBVMLMtpjZqqi2Qz4OZlYUrP8XMytKkDruC36/VpjZy2aWEbXsR0Eda81sRFR7fLPN3RPqAbQBPgV6AUcDy4EB8e5XA/3tDJwcTH8D+BgYAPwEmBy0TwamB9PnA68CBgwD/hzvGurU86/AM8Bvg/lfA2OC6ZnADcH0jcDMYHoM8Hy8+16njjnANcH00UBGazwmQFdgHXBs1PEY31qOC5APnAysimo7pOMAZAJ/Df5tF0y3S4A6zgVSg+npUXUMCHKrLdAzyLM2iZBtcf+FrucHezqwMGr+R8CP4t2vQ+j/fKCQyKeEOwdtnYl8kAzgv4GxUevXrBfvB5ANvA4MB34b/MfbFvVLXXNsgIXA6cF0arCexbuGoD8nBCFpddpb4zHpCqwPwi41OC4jWtNxAXrUCcpDOg7AWOC/o9prrRevOuosuxT4VTBdK7P2H5NEyLZEHNLZ/wu+34agLeEFl88nAX8GOrp7WbBoE9AxmE7k+h4Cbgf2BfPfBHa5e1UwH93XmjqC5buD9RNBT2Ar8ItgeGq2maXRCo+Ju5cC9wOfAWVEfs7LaJ3HZb9DPQ4Je3yiTCBydQIJXEciBn6rZGbpwEvALe7+efQyj7ycJ/T9r2Z2AbDF3ZfFuy/NIJXI5ffP3f0koILI0EGN1nBMAILx7YuJvIh1AdKA8+LaqWbUWo5DQ8zsDqAK+FW8+9KYRAz8UqBb1Hx20JawzOwoImH/K3efGzRvNrPOwfLOwJagPVHr+y5wkZmVAM8RGdaZAWSY2f7vXIrua00dwfITgO0t2eEGbAA2uPufg/kXibwAtLZjAnAOsM7dt7p7JTCXyLFqjcdlv0M9Dgl7fMxsPHABcGXw4gUJXEciBv67QO/gLoSjibzx9Eqc+3RQZmbA48Aad/9p1KJXgP13ExQRGdvf3z4uuCNhGLA76vI2btz9R+6e7e49iPzM33D3K4HFwOXBanXr2F/f5cH6CXGm5u6bgPVm1jdoOhtYTSs7JoHPgGFmdlzwu7a/llZ3XKIc6nFYCJxrZu2CK55zg7a4MrPziAyBXuTuf4ta9AowJrhjqifQG3iHRMi2ln7jo4lvjpxP5G6XT4E74t2fRvp6BpFL0hXAB8HjfCLjpq8DfwH+B8gM1jfg0aC2lcDQeNdQT00FfH2XTi8iv6yfAC8AbYP2Y4L5T4LlveLd7zo1DAGWBsdlHpG7O1rlMQGmAB8Bq4CniNz90SqOC/AskfceKolceV19OMeByBj5J8HjqgSp4xMiY/L7/9/PjFr/jqCOtcDIqPa4Zpu+WkFEJCQScUhHRERiQIEvIhISCnwRkZBQ4IuIhIQCX0QkJBL5j5iLxISZVRO57W+/S9y9JE7dEWkxui1TQsfMyt09vQX3l+pff++NSNxoSEekDjPrbGZLzOyD4DvozwzazzOz98xsuZm9HrRlmtm84DvR3zazQUH7PWb2lJn9L/CUmbU3s5fM7N3g8d04lighpSEdCaNjzeyDYHqdu19aZ/kVRL7G9r/MrA1wnJm1Bx4D8t19nZllButOAd5390vMbDjwSyKf8oXI96Kf4e57zOwZ4EF3/6OZdSfy1QD9Y1ijyAEU+BJGe9x9SAPL3wWeCL4Ub567f2BmBcASd18H4O47gnXPAP4uaHvDzL5pZscHy15x9z3B9DnAgMjX4QBwvJmlu3t585Ul0jAFvkgd7r7EzPKBUcCTZvZTYOdhPFVF1HQKMMzdv2yOPoocDo3hi9RhZt8CNrv7Y8BsIl+t/DaQH3z7IVFDOn8ArgzaCoBtXufvIQQWATdH7aOhKwyRmNAZvsiBCoDbzKwSKAfGuftWM7sWmGtmKUS+w70QuIfI8M8K4G98/bW/dU0EHg3WSwWWANfHtAqROnRbpohISGhIR0QkJBT4IiIhocAXEQkJBb6ISEgo8EVEQkKBLyISEgp8EZGQ+P93BlN6SIioDwAAAABJRU5ErkJggg==\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "D_0IvLzX1V4X",
        "colab_type": "text"
      },
      "source": [
        "##LDA的knn"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "JnQNy5MT1Vek",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 351
        },
        "outputId": "01f29083-14d2-4b44-a64f-250b4a4cf2c0"
      },
      "source": [
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "from sklearn import datasets\n",
        "\n",
        "from utils import train_test_split, normalize, accuracy_score\n",
        "from utils import euclidean_distance, Plot\n",
        "class KNN():\n",
        "\n",
        "    def __init__(self,k=5):\n",
        "\n",
        "        self.k = k\n",
        "    def predict(self, X_test, X_train, y_train):\n",
        "\n",
        "        y_predict = np.zeros(X_test.shape[0])\n",
        "\n",
        "        for i in range(X_test.shape[0]):\n",
        "\n",
        "            distances = np.zeros((X_train.shape[0], 2)) #测试的数据和训练的各个数据的欧式距离\n",
        "\n",
        "            for j in range(X_train.shape[0]):\n",
        "                dis = euclidean_distance(X_test[i], X_train[j]) #计算欧式距离\n",
        "                label = y_train[j] #测试集到的每个训练集的数据的分类标签\n",
        "                distances[j] = [dis, label]\n",
        "\n",
        "                # argsort()得到测试集到训练的各个数据的欧式距离从小到大排列并且得到序列，然后再取前k个.\n",
        "                k_nearest_neighbors = distances[distances[:, 0].argsort()][:self.k]\n",
        "\n",
        "                #利用np.bincount统计k个近邻里面各类别出现的次数\n",
        "                counts = np.bincount(k_nearest_neighbors[:, 1].astype('int'))\n",
        "\n",
        "                #得出每个测试数据k个近邻里面各类别出现的次数最多的类别\n",
        "                testLabel = counts.argmax()\n",
        "                y_predict[i] = testLabel\n",
        "\n",
        "        return y_predict\n",
        "\n",
        "def run():\n",
        "    #初始化knn\n",
        "    model = KNN(k=5)\n",
        "    y_pred = model.predict(X_test_LDA, X_train_LDA, y_train_LDA)\n",
        "\n",
        "    accuracy = accuracy_score(y_test_LDA, y_pred)\n",
        "\n",
        "    print(\"Accuracy:\", accuracy)\n",
        "\n",
        "    # 用图画出测试集的分类情况\n",
        "    Plot().plot_in_2d(X_test_LDA, y_pred, title=\"KNN\", accuracy=accuracy)\n",
        "\n",
        "\n",
        "if __name__ == \"__main__\":\n",
        "    run()"
      ],
      "execution_count": 25,
      "outputs": [
        {
          "output_type": "error",
          "ename": "KeyboardInterrupt",
          "evalue": "ignored",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-25-dbbea75fc279>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     49\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     50\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0m__name__\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"__main__\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 51\u001b[0;31m     \u001b[0mrun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
            "\u001b[0;32m<ipython-input-25-dbbea75fc279>\u001b[0m in \u001b[0;36mrun\u001b[0;34m()\u001b[0m\n\u001b[1;32m     38\u001b[0m     \u001b[0;31m#初始化knn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     39\u001b[0m     \u001b[0mmodel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mKNN\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 40\u001b[0;31m     \u001b[0my_pred\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpredict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX_test_LDA\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX_train_LDA\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_train_LDA\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     41\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     42\u001b[0m     \u001b[0maccuracy\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0maccuracy_score\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my_test_LDA\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_pred\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m<ipython-input-25-dbbea75fc279>\u001b[0m in \u001b[0;36mpredict\u001b[0;34m(self, X_test, X_train, y_train)\u001b[0m\n\u001b[1;32m     24\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     25\u001b[0m                 \u001b[0;31m# argsort()得到测试集到训练的各个数据的欧式距离从小到大排列并且得到序列，然后再取前k个.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 26\u001b[0;31m                 \u001b[0mk_nearest_neighbors\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdistances\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mdistances\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margsort\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     27\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     28\u001b[0m                 \u001b[0;31m#利用np.bincount统计k个近邻里面各类别出现的次数\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NVmhpLy3sEHP",
        "colab_type": "text"
      },
      "source": [
        "#KPCA降维"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "NITCJaacsDip",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 281
        },
        "outputId": "2bd0fe87-924b-4f7f-e0a1-87d36a7525cc"
      },
      "source": [
        "#PCA算法的非线性扩展\n",
        "from sklearn.datasets import load_iris\n",
        "from sklearn.decomposition import KernelPCA\n",
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "from scipy.spatial.distance import pdist, squareform\n",
        "X = feature_vectors\n",
        "Y = correct_facies_labels\n",
        "sklearn_kpca = KernelPCA(n_components=4, kernel=\"rbf\", gamma=15)\n",
        "data_3 = sklearn_kpca.fit_transform(X)\n",
        "plt.subplot(122)\n",
        "plt.title(\"sklearn_KPCA\")\n",
        "plt.scatter(data_3[:, 0], data_3[:, 1], c = Y)\n",
        "plt.show()"
      ],
      "execution_count": 26,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "c8egS-b6t3g-",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "from sklearn.model_selection import train_test_split\n",
        "X_train_KPCA,X_test_KPCA,y_train_KPCA,y_test_KPCA=train_test_split(data_3,correct_facies_labels,test_size=0.2,random_state=42)"
      ],
      "execution_count": 27,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ldZxUEk_uI4Y",
        "colab_type": "text"
      },
      "source": [
        "##KPCA的随机森林"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "OhZ9x7GwuIT5",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 711
        },
        "outputId": "54ac76d6-89ed-4ebc-b9ae-6ab3271b58f6"
      },
      "source": [
        "from sklearn.ensemble import RandomForestClassifier\n",
        "from sklearn import metrics\n",
        "\n",
        "rfmodel = RandomForestClassifier()\n",
        "rfmodel.fit(X_train_KPCA,y_train_KPCA)\n",
        "print('model')\n",
        "print(rfmodel)\n",
        "\n",
        "ypredrf1 = rfmodel.predict(X_test_KPCA)\n",
        "print('confusion matrix')\n",
        "print(metrics.confusion_matrix(y_test_KPCA, ypredrf1))\n",
        "print('classification report')\n",
        "print(metrics.classification_report(y_test_KPCA, ypredrf1))\n",
        "print('Accuracy : %f' % (metrics.accuracy_score(y_test_KPCA, ypredrf1)))"
      ],
      "execution_count": 28,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "model\n",
            "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,\n",
            "                       criterion='gini', max_depth=None, max_features='auto',\n",
            "                       max_leaf_nodes=None, max_samples=None,\n",
            "                       min_impurity_decrease=0.0, min_impurity_split=None,\n",
            "                       min_samples_leaf=1, min_samples_split=2,\n",
            "                       min_weight_fraction_leaf=0.0, n_estimators=100,\n",
            "                       n_jobs=None, oob_score=False, random_state=None,\n",
            "                       verbose=0, warm_start=False)\n",
            "confusion matrix\n",
            "[[  4  41   0   0   0   0   0   1   0]\n",
            " [  2 144   2   2   0   1   0   1   1]\n",
            " [  2 122   2   0   0   0   0   0   0]\n",
            " [  0  27   0   1   0   0   0   0   0]\n",
            " [  0  44   0   1   1   0   0   0   1]\n",
            " [  0  94   0   1   1   1   0   2   1]\n",
            " [  0  21   0   0   0   0   0   0   1]\n",
            " [  0  90   0   1   0   0   0   2   1]\n",
            " [  0   2   0   0   0   0   0   0  29]]\n",
            "classification report\n",
            "              precision    recall  f1-score   support\n",
            "\n",
            "           1       0.50      0.09      0.15        46\n",
            "           2       0.25      0.94      0.39       153\n",
            "           3       0.50      0.02      0.03       126\n",
            "           4       0.17      0.04      0.06        28\n",
            "           5       0.50      0.02      0.04        47\n",
            "           6       0.50      0.01      0.02       100\n",
            "           7       0.00      0.00      0.00        22\n",
            "           8       0.33      0.02      0.04        94\n",
            "           9       0.85      0.94      0.89        31\n",
            "\n",
            "    accuracy                           0.28       647\n",
            "   macro avg       0.40      0.23      0.18       647\n",
            "weighted avg       0.40      0.28      0.17       647\n",
            "\n",
            "Accuracy : 0.284389\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/sklearn/metrics/_classification.py:1272: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n",
            "  _warn_prf(average, modifier, msg_start, len(result))\n"
          ],
          "name": "stderr"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qhNL990iuxYF",
        "colab_type": "text"
      },
      "source": [
        "所以证明我们这个数据不是非线性的  粒子群优化"
      ]
    }
  ]
}